/***************************************************************************************************
  *Copyright(C),2010-2017,Sumscope
  *FileName	:  FieldDecode.hpp
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2017/08/07
  *Desc		:  //������Ҫ˵���˳����ļ���ɵ���Ҫ����
  *Relation :  
  *Others	:  //��������˵��
  *Function :  //��Ҫ�����б���ÿ����¼Ӧ���������������ܼ�Ҫ˵��
  *History	:  //�޸���ʷ��¼�б���ÿ���޸ļ�¼Ӧ�����޸����ڡ��޸��߼��޸����ݼ��
***************************************************************************************************/
#ifndef FIELDDECODE_HPP_49A02771_04C6_43F6_8F67_FDEB6D62B3BF
#define FIELDDECODE_HPP_49A02771_04C6_43F6_8F67_FDEB6D62B3BF
#include "FieldDataType.h"
// �������ڶ��ֶν��н����ģ��ĺ�
template<typename TYPE, int N>
int FieldTypeDecode(const void* data, void* buf, int capcity, int& type){
	//DECODEARR(N); 
	memcpy(buf, data, N);
	type = (kFieldDataTypeChar << 16) + N;
	int len = strlen((const char*)data);
	len = len >= N ? N : len;
	return len;
}

#define TPL_INSTANCE(TYPE,N,ETYPE)  template<> int FieldTypeDecode<TYPE,N>(const void* data, void* buf, int capcity, int& type){DECODE(TYPE, ETYPE);}
#define TPL_INSTANCE_ARR(TYPE) template<> int FieldTypeDecode<TYPE, 1>(const void* data, void* buf, int capcity, int& type){DECODEARR(sizeof(TYPE));}
#define TPL_INSTANCE_STR() template<> int FieldTypeDecode<string, 1>(const void* data, void* buf, int capcity, int& type){DECODESTR();}

// �������������͵Ľ���ģ��
static_assert(sizeof(tDate8) == sizeof(tBondCode), "tDate8,tBondCode must equal size,or add TPL_INSTANCE_ARR(tBondCode)");
//TPL_INSTANCE_ARR(tDate8);
//TPL_INSTANCE_ARR(tBondKey);
////TPL_INSTANCE_ARR(tBondCode);//��tDate8�ظ�
//TPL_INSTANCE(int, 1, kFieldDataTypeInt);
//TPL_INSTANCE(float, 1, kFieldDataTypeFloat);
//TPL_INSTANCE(bool, 1, kFieldDataTypeBool);
//TPL_INSTANCE(double, 1, kFieldDataTypeDouble);
//TPL_INSTANCE(UINT, 1, kFieldDataTypeUINT);
//TPL_INSTANCE_STR();

// ȫ��չ����ʽ
template<> inline int FieldTypeDecode<tDate8, 1>(const void* data, void* buf, int capcity, int& type){
	memcpy(buf, data, sizeof(tDate8));
	type = (kFieldDataTypeChar << 16) + sizeof(tDate8);
	int len = strlen((const char*)data);
	len = len >= sizeof(tDate8) ? (sizeof(tDate8) - 1) : len;
	return len;
}
template<> inline int FieldTypeDecode<tBondKey, 1>(const void* data, void* buf, int capcity, int& type){
	memcpy(buf, data, sizeof(tBondKey));
	type = (kFieldDataTypeChar << 16) + sizeof(tBondKey);
	int len = strlen((const char*)data);
	len = len >= sizeof(tBondKey) ? (sizeof(tBondKey) - 1) : len;
	return len;
}
template<> inline int FieldTypeDecode<char, 1>(const void* data, void* buf, int capcity, int& type){
	*(char*)buf = *(const char*)data;
	type = (kFieldDataTypeChar << 16) + 1;
	return sizeof(char);
}
template<> inline int FieldTypeDecode<int, 1>(const void* data, void* buf, int capcity, int& type){
	*(int*)buf = *(const int*)data;
	type = (kFieldDataTypeInt << 16) + 1;
	return sizeof(int);
}
template<> inline int FieldTypeDecode<float, 1>(const void* data, void* buf, int capcity, int& type){
	*(float*)buf = *(const float*)data;
	type = (kFieldDataTypeFloat << 16) + 1;
	return sizeof(float);
}
template<> inline int FieldTypeDecode<bool, 1>(const void* data, void* buf, int capcity, int& type){
	*(bool*)buf = *(const bool*)data;
	type = (kFieldDataTypeBool << 16) + 1;
	return sizeof(bool);
}
template<> inline int FieldTypeDecode<double, 1>(const void* data, void* buf, int capcity, int& type){
	*(double*)buf = *(const double*)data;
	type = (kFieldDataTypeDouble << 16) + 1;
	return sizeof(double);
}
template<> inline int FieldTypeDecode<uint32_t, 1>(const void* data, void* buf, int capcity, int& type){
	*(uint32_t*)buf = *(const uint32_t*)data;
	type = (kFieldDataTypeUINT << 16) + 1;
	return sizeof(uint32_t);
}
template<> inline int FieldTypeDecode<std::string, 1>(const void* data, void* buf, int capcity, int& type){
	const std::string* pstr = (const std::string*)(data);
	int len = ((int)pstr->size() >= capcity) ? (capcity - 1) : pstr->size();
	if (len > 0)memcpy(buf, pstr->c_str(), len);
	type = (kFieldDataTypeString << 16) + pstr->capacity();
	return len;
}


#endif
